package com.ruoyi.member.interceptor;

import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.annotation.AllowAnonymous;
import com.ruoyi.common.context.AppUserContext;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.RedisKeyEnum;
import com.ruoyi.common.enums.member.MemberErrorCode;
import com.ruoyi.common.exception.modules.MemberException;
import com.ruoyi.member.utils.JwtUtil;
import com.ruoyi.common.vo.AppUser;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

@Component
@Slf4j
public class AuthorizationInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisCache redisCache;

    @Value("${wechat.jwt.user-secret-key}")
    private String userSecretKey;
    @Value("${ruoyi.env}")
    private String env;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) {
        if (!(object instanceof HandlerMethod)) {
            return true;
        }

        //只拦截移动端接口，本地也不拦截
        if (!request.getRequestURI().startsWith("/portal")) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) object;
        Method method = handlerMethod.getMethod();

        //跳过验证注解
        if (method.isAnnotationPresent(AllowAnonymous.class)) {
            AllowAnonymous passToken = method.getAnnotation(AllowAnonymous.class);
            if (passToken.required()) {
                return true;
            }
        }

        String token = request.getHeader("Authorization");

        if (StrUtil.isBlank(token)) {
            log.error(MemberErrorCode.NO_TOKEN.getMsg());
            throw new MemberException(MemberErrorCode.NO_TOKEN.getCode(), MemberErrorCode.NO_TOKEN.getMsg());
        }

        Object userId;
        try {
            //token解密后获取用户信息 后面加到过滤器里获取用户信息的
            Claims claims = JwtUtil.parseJWT(userSecretKey, token);
            userId = claims.get("user_id");
        } catch (Exception e) {
            log.error(MemberErrorCode.TOKEN_INVALID.getMsg(), e);
            throw new MemberException(MemberErrorCode.TOKEN_INVALID.getCode(), MemberErrorCode.TOKEN_INVALID.getMsg());
        }

        if (!redisCache.hasKey(RedisKeyEnum.LOGIN_TOKEN.getPrefix() + userId)) {
            log.error(MemberErrorCode.LOGIN_EXPIRED.getMsg());
            throw new MemberException(MemberErrorCode.LOGIN_EXPIRED.getCode(), MemberErrorCode.LOGIN_EXPIRED.getMsg());
        }

        AppUser appUser = redisCache.getCacheObject(RedisKeyEnum.LOGIN_TOKEN.getPrefix() + userId);
        AppUserContext.setUser(appUser);

        return true;
    }
}